home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / program / asm32.zip / DATA.DOC < prev    next >
Text File  |  1995-11-30  |  40KB  |  1,275 lines

  1.  
  2. *******************************  DATA  *************************************
  3.  
  4. ASM32 data manipulation subroutines Copyright (C) 1993 - 1995 Douglas Herr
  5. all rights reserved
  6.  
  7. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  8.  
  9. $SSORT:      generic Shell sort engine; calling program supplies Compare
  10.              and Exchange code
  11. Source:      $ssort.asm
  12.  
  13. Call with:   [ESI] = address of first item to sort
  14.              [EDI] = address of last item to sort
  15.              EAX   = length of each item
  16.              EBX   = address of compare routine
  17.              EDX   = address of exchange routine
  18.  
  19.              $SSORT can be used to sort data of any fixed size, including
  20.              user-defined records.  The calling program specifies the near
  21.              address of the comparison code, and the near address of the
  22.              exchange code.  The compare code must save all registers except
  23.              EAX, and is called with ESI = near address of first record to
  24.              compare, and EDI = near address of the second record to compare.
  25.              $SSORT expects integer comparisons to be signed.  $SSORT calls
  26.              the exchange subroutine with ES:[EDI] and DS:[ESI] pointing to
  27.              the records to be exchanged, and ECX = number of bytes to
  28.              exchange.  ASM32's SWAPB subroutine may be used as the exchange
  29.              code.
  30.  
  31. Returns:     nothing
  32. Uses:        nothing; all flags and registers are saved
  33.  
  34. Example on next page
  35.  
  36.  
  37. $SSORT Example:
  38.  
  39. extrn   $ssort:near, swapb:near
  40.  
  41. include dataseg.inc
  42.  
  43. intdata dw 12,13,120,160
  44.         dw 12,13
  45.         dw 60,110,120,13
  46.         dw 120,160
  47.         dw 100,90
  48.         dw 20,150,12,100
  49.         dw 118
  50. lastint dw 25
  51. nosort  dw ?                       ; anything past lastint not sorted
  52.                                    ; in this example
  53. @curseg ends
  54.  
  55. include codeseg.inc
  56.  
  57.         .
  58.         .
  59.         .
  60.         lea     esi,intdata        ; point to first integer
  61.         lea     edi,lastint        ; point to last integer to sort
  62.         mov     eax,2              ; size of data record
  63.         lea     ebx,compare        ; point EBX to comparison code
  64.         lea     edx,swapb          ; use ASM32 subroutine for exchange
  65.         call    $ssort
  66.         ret
  67.  
  68. ;
  69. ; For some unexplained reason I want to base the sort on
  70. ; only the lower byte of each integer record.
  71. ; $SSORT expects this to be a signed comparison, but my bytes are
  72. ; unsigned so I'll convert each one to a signed dword.
  73. ; I'm using DWORDS instead of WORDS because DWORDS in a 32-bit segment
  74. ; are faster and produce smaller code.
  75. ;
  76. ; Your data will be sorted low-to-high or high-to-low depending on
  77. ; your comparison.
  78. ;
  79. compare:
  80.         push    ebx                ; need to save this register
  81.         movzx   eax,byte ptr [esi]
  82.         movzx   ebx,byte ptr [edi]
  83.         cmp     ebx,eax            ; do the comparison
  84.         pop     ebx                ; restore register
  85.         ret
  86.  
  87.  
  88. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  89.  
  90. CHRDEL:      deletes a character from a string
  91.              The resulting space is closed by moving the remaining
  92.              characters forward
  93. Source:      chrdel.asm (strlen.asm)
  94.  
  95. Call with:   EBX pointing to an ASCIIZ string
  96.              EAX = offset from EBX to character to delete
  97. Returns:     ECX = new string length
  98. Uses:        ECX
  99. Example:     lea   ebx,string         ; EBX points to string
  100.              mov   eax,3              ; delete character at [EBX+3]
  101.              call  chrdel             ; delete the character, shorten string
  102.  
  103.  
  104. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  105.  
  106. COLORATTR:   calculate a color attribute for ASM32's text-mode subroutines.
  107.              Intended for 16-color text modes.
  108. Source:      coloratt.asm
  109. Call with:   AL = foreground color (0 - 15)
  110.              AH = background color (0 - 15)
  111. Returns:     AH = color attribute
  112. Uses:        AX
  113. Example:
  114.  
  115. include codeseg.inc
  116.         .
  117.         .
  118.         .
  119.         mov    al,hired            ; bright red
  120.         mov    ah,blue             ; blue
  121.         call   colorattr           ; this should get their attention
  122.         mov    warning,ah          ; save the attribute
  123.  
  124. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  125.  
  126. CSET:        centers a string in a fixed field
  127. Source:      cset.asm (strlen.asm)
  128.  
  129. Call with:   EDI pointing to address of field string
  130.              ESI pointing address of string to be centered in the field
  131.              Both strings must be zero-terminated (ASCIIZ).  The field
  132.              string may not contain any nul characters except for the
  133.              terminator.
  134. Returns:     CF = 0 if no error
  135.              CF = 1 if string was truncated to fit in the field
  136. Uses:        CF; all other flags and registers are saved
  137. Example:
  138.  
  139.              lea   edi,field             ; field string
  140.              lea   esi,source            ; string to be centered in field
  141.              call  cset
  142.  
  143.  
  144. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  145.  
  146. DAYNAME:     returns a pointer to an ASCII string for specified day
  147.              of the week
  148. Source:      dname.asm ($mname.asm)
  149.  
  150. Call with:   AX = day of week (1 - 7, Monday = 1)
  151. Returns:     [EBX] = pointer to day name string
  152.              ECX = length of new string
  153.              Note that the day name string is not zero-terminated
  154.              strndup may be used to copy the string to near data.
  155. Uses:        EBX, ECX
  156. Example:     mov    ax,day
  157.              call   dayname
  158.  
  159.  
  160.  
  161. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  162.  
  163. FILL4, FILL4b: fill a buffer with specified 4-byte data
  164. Source:        fill4.asm
  165.  
  166. Call with:   ESI pointing to 4-byte data (integer, float or other)
  167.              EDI pointing to buffer
  168.              ECX = number of 4-byte data blocks to fill in buffer
  169.              Fill4b: EBX = byte increment between data blocks
  170. Returns:     nothing
  171. Uses:        nothing
  172. Example:
  173.  
  174. include codeseg.inc
  175.  
  176. extrn   fill4:near
  177.  
  178. ; data
  179. wonowon dd 101.      ; float4 value
  180. buffer  dd ?         ; program allocates buffer, stores address here
  181.  
  182. ; code
  183.         .
  184.         .
  185.         .
  186.         lea   edi,buffer
  187.         lea   esi,wonowon  ; fill every other 4-byte block in far segment
  188.         mov   ebx,8        ; skip 4 bytes between data blocks
  189.         mov   cx,25        ; do it 25 times
  190.         cal   fill4
  191.  
  192.  
  193.  
  194. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  195.  
  196. FILL8, FILL8b: fill a buffer with specified 8-byte data
  197. Source:        fill8.asm
  198.  
  199. Call with:   ESI pointing to 8-byte data (integer, float or other)
  200.              EDI pointing to buffer
  201.              ECX = number of 8-byte data blocks to fill in buffer
  202.              Fill8b: EBX = byte increment between data blocks
  203. Returns:     nothing
  204. Uses:        nothing
  205. Example:     see Fill4
  206.  
  207.  
  208.  
  209.  
  210. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  211.  
  212. FSTRISTR:    search for a string in a disk file, case insensetive
  213. Source:      fstristr.asm (mload.asm, $strstr.asm, strnlwr.asm)
  214.  
  215. FSTRSTR:     search for a string in a disk file, case sensetive
  216. Source:      fstrstr.asm (mload.asm, strlen.asm, $strstr.asm)
  217.  
  218. Call with:   EDX pointing to file name
  219.              ESI pointing to string to find
  220.              EAX = initial offset in file
  221.              CAUTION: Prior to ASM32 version 3.4, FSTRSTR and FSTRISTR
  222.                       required different parameters.  If you are upgrading
  223.                       from an earlier version of ASM32 and have used either
  224.                       of these subroutines, you will need to change
  225.                       parameters.
  226. Returns:     if CF = 0, EAX is the offset of the string in the file
  227.              if CF = 1, EAX = DOS or other error code
  228.                         EAX = -1 if insufficient memory (unlikely)
  229.  
  230. Uses:        EAX, flags
  231.  
  232. Example:
  233.  
  234. include codeseg.inc
  235.  
  236. extrn   fstrstr:near
  237.  
  238. ; data
  239. string   db 'A String In The File',0
  240. filename db 'anyold.fil',0
  241.  
  242. ; code
  243. yoursub proc    near
  244.         mov     edx,offset filename
  245.         mov     esi,offset string  ; ESI points to the string
  246.         xor     eax,eax            ; shearch entire file
  247.         call    fstrstr            ; returns with EAX = string offset
  248.         jc      short no_good      ;  or error code
  249.  
  250.  
  251. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  252.  
  253. GETCMD:      isolates command line parameters
  254.              GetCMD assumes that parameters are separated by
  255.              one or more spaces
  256. Source:      getcmd.asm
  257.  
  258. Call with:   AL = parameter number (first command line parameter = 0)
  259.  
  260. Returns:     if ECX = 0, no command parameter(AL)
  261.              if ECX <> 0, ECX = length of parameter string
  262. (CauseWay FLAT model)
  263.              [EBX] = near pointer to command line parameter
  264. (all except CauseWay FLAT model)
  265.              ES:[EBX] = far pointer to command line parameter
  266.              Version 2.0: Note that GETCMD does not copy the command
  267.              parameter string to near data.  It returns a far address to
  268.              the command string which you may copy to near data with STRNDUP
  269.              if you wish.
  270.  
  271. Uses:        ES (except CW FLAT model), EBX, ECX, flags
  272. Example:
  273.  
  274. extrn   getcmd:near
  275.  
  276. include codeseg.inc
  277.  
  278.          .
  279.          .
  280.          .
  281.  
  282.         mov     al,0        ; get first parameter
  283.         call    getcmd      ; returns with ES:[EBX] pointing to parameter
  284.                             ; and ECX = length of parameter
  285.         jecxz   no_parameters
  286. IFNDEF  FLATMODEL
  287.         call    strndup     ; copy to near data
  288. ENDIF
  289.          .
  290.          .
  291.          .
  292.  
  293.  
  294. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  295.  
  296. I2TOSTR:     convert an integer value to an ASCIIZ string
  297. Source:      i2tostr.asm (i4tostr.asm)
  298.  
  299. I4TOSTR:     convert a long integer value to an ASCIIZ string
  300. Source:      i4tostr.asm
  301.  
  302.              ASM32's TPrint, GPrint and other 'print' subroutines require
  303.              a string argument.  Numeric data must be converted to a string
  304.              before printing.
  305.  
  306. Call with:   [ESI] pointing to a buffer space; must be 12 bytes or bigger
  307.              (i2tostr) AX = integer value
  308.              (i4tostr) EAX = long integer value
  309.  
  310. Returns:     ASCIIZ string at [ESI]; numerals are right-justified
  311. Uses:        nothing; all registers and flags are saved
  312. Supports:    (i2tostr) signed 2-byte integers
  313.              (i4tostr) signed 4-byte integers
  314. Example:
  315.  
  316. include codeseg.inc
  317.  
  318. extrn  i2tostr:near
  319.  
  320. ; data
  321. nbuffer  db 12 dup(?)
  322.  
  323. ; code
  324.  
  325.        .
  326.        .
  327.        .
  328.        lea   esi,nbuffer
  329.        mov   ax,32750      ; integer value
  330.        call  i2tostr
  331.  
  332.  
  333.  
  334. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  335.  
  336. LSET:        left-justifies a string in a fixed field
  337. Source:      lset.asm (strlen.asm)
  338.  
  339. Call with:   EDI = address of field string
  340.              ESI = address of string to be justified in the field
  341.              Both strings must be zero-terminated (ASCIIZ).  The field
  342.              string may not contain any NUL characters except for the
  343.              terminator.
  344. Returns:     CF = 0 if no error
  345.              CF = 1 if string was truncated to fit in the field
  346. Uses:        CF
  347.              all other flags and registers saved
  348. Example:
  349.              lea   edi,field             ; field string
  350.              lea   esi,source            ; string to be justified in field
  351.              call  lset
  352.  
  353.  
  354. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  355.  
  356. LTRIM:       remove leading blanks from an ASCIIZ string
  357. Source:      ltrim.asm (strlen.asm)
  358.  
  359. Call with:   EBX pointing to string
  360. Returns:     ECX = new string length
  361. Uses:        ECX
  362. Example:     lea    ebx,string
  363.              call   ltrim
  364.  
  365.  
  366.  
  367.  
  368. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  369.  
  370. MAXI2, MAXI2b: find maximum value in a signed integer array
  371. Source:        maxi2.asm
  372.  
  373. MINI2, MINI2b: find minimum value in a signed integer array
  374. Source:        mini2.asm
  375.  
  376. MAXU2, MINU2b: find maximum value in an unsigned integer array
  377. Source:        maxu2.asm
  378.  
  379. MINU2, MINU2b: find minimum value in an unsigned integer array
  380. Source:        minu2.asm
  381.  
  382. Call with:   EDI pointing to the array
  383.              ECX = number of array elements
  384.              For max/min?2b, call with EBX = byte increment between
  385.              array elements.  Max/min?2 assume increment = 2.
  386. Returns:     EAX = array element number with maximum value
  387.              see example to calculate address of maximum value
  388.              if subroutine was called with ECX = 0, CF = 1
  389. Uses:        EAX, CF
  390. Example:
  391.  
  392. include codeseg.inc
  393.  
  394. extrn  maxi2:near
  395.  
  396. ; data
  397.  
  398. integers     dw 140 dup(0)
  399.  
  400. ; code
  401.              .     ; program establishes array values
  402.              .
  403.              .
  404.              lea    edi,integers
  405.              mov    ecx,140        ; search the entire array
  406.              call   maxi2
  407.              shl    eax,1          ; convert word offset to byte offsest
  408.              add    edi,eax        ; EDI points to the maximum value
  409.                                    ; With max/min?2b, the offset of the
  410.                                    ; value is EDI + (EAX * EBX).
  411.  
  412. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  413.  
  414. MAXI4, MAXI4b: find maximum value in a signed 4-byte integer array
  415. Source:        maxi4.asm
  416.  
  417. MINI4, MINI4b: find minimum value in a signed 4-byte integer array
  418. Source:        mini4.asm
  419.  
  420. MAXU4, MAXU4b: find maximum value in an unsigned 4-byte integer array
  421. Source:        maxu4.asm
  422.  
  423. MINU4, MINU4b: find minimum value in an unsigned 4-byte integer array
  424. Source:        minu4.asm
  425.  
  426. Call with:   EDI pointing to the array
  427.              ECX = number of array elements
  428.              For max/min?4b, call with EBX = byte increment between
  429.              array elements.  Max/min?4 assume increment = 4.
  430. Returns:     EAX = array element number with maximum value
  431.              see example to calculate address of maximum value.
  432.              if subroutine was called with ECX = 0, CF = 1
  433. Uses:        EAX, CF
  434. Example:
  435.  
  436. include codeseg.inc
  437.  
  438. extrn  maxi4:near
  439.  
  440. ; data
  441.  
  442. int4         dd 140 dup(0)
  443.  
  444. ; code
  445.              .     ; program establishes array values
  446.              .
  447.              .
  448.              lea    edi,int4
  449.              mov    ecx,140        ; search the entire array
  450.              call   maxi4
  451.              shl    eax,2          ; convert dword offset to byte offset
  452.              add    edi,eax        ; EDI points to the maximum value
  453.                                    ; With max/min?4b, the offset of the
  454.                                    ; value is EDI + (EAX * EBX).
  455.  
  456. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  457.  
  458. MEMCOPY:     copy data, checking for overlap if ES = DS
  459. Source:      memcopy.asm
  460.  
  461. Call with:   DS:[ESI] = source address
  462.              ES:[EDI] = destination address
  463.              ECX = bytes to move
  464. Returns:     nothing
  465. Uses:        nothing
  466.  
  467. Example:
  468.  
  469. extrn   memcopy:near
  470.  
  471. include dataseg.inc
  472.  
  473. farmem      dw ?            ; selector of far memory block
  474. source      dd ?            ; offset in far memory block
  475. destination dd ?            ; destination offset
  476.  
  477. @curseg ends
  478.  
  479. include codeseg.inc
  480.  
  481.         .
  482.         .
  483.         .
  484.         push   ds
  485.         push   es
  486.         mov    esi,source
  487.         mov    edi,destination
  488.         mov    ax,farmem
  489.         mov    ds,ax
  490.         mov    es,ax
  491.         call   memcopy
  492.         pop    es
  493.         pop    ds
  494.  
  495.  
  496.  
  497. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  498.  
  499. MONTHNAME:   returns a pointer to an ASCII string for specified month
  500. Source:      mname.asm ($mname.asm)
  501.  
  502. Call with:   AX = month (1 - 12, January = 1)
  503. Returns:     [EBX] = pointer to month name string
  504.              ECX = length of month string
  505.              Note that the month name string is not zero-terminated
  506.              strndup may be used to copy the string to near data.
  507. Uses:        EBX, ECX
  508. Example:     mov    ax,month
  509.              call   monthname
  510.  
  511.  
  512. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  513.  
  514. PATH:        finds path strings in program enviornment
  515.              isolates each path in "PATH=" part of enviornment
  516. Source:      path.asm (strlen.asm)
  517.  
  518. Call with:   EAX = path number
  519. Returns:     if ECX =0, path(EAX) does not exist.
  520.              if ECX <> 0, ECX = length of path string, and
  521. (CauseWay FLAT model)
  522.              [EBX] = near pointer to path(EAX).
  523. (all except CauseWay FLAT model)
  524.              ES:[EBX] = far pointer to path(EAX).
  525.  
  526.              The path string is located in the program's environment
  527.              block.  The first path in the enviornment is path(0).  Note
  528.              that the path string is NOT zero-terminated.
  529.  
  530. (all except CauseWay FLAT model)
  531.              Version 2.0: Note that PATH does not copy the path string to
  532.              near data.  It returns a far address to the path string which
  533.              you may copy to near data with STRNDUP if you wish.
  534.  
  535. Uses:        ES (except CW FLAT model), EBX, ECX, flags
  536. Example:     
  537.  
  538. extrn   path:near
  539.  
  540. include codeseg.inc
  541.  
  542.          .
  543.          .
  544.          .
  545.  
  546.         xor     eax,eax      ; start with the first path
  547. find_path:
  548.         call    path
  549.         jecxz   no_path      ; exit if no more paths
  550. IFNDEF  FLATMODEL
  551.         call    strndup      ; copy to near data
  552. ENDIF
  553.          .
  554.          .
  555.          .
  556.         inc     eax          ; look for next path
  557.         jmp     find_path
  558.  
  559. no_path:
  560.          .
  561.          .
  562.  
  563. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  564.  
  565. RANDOM:      generates a near-random number
  566. Source:      random.asm
  567.  
  568. Call with:   no parameters
  569. Returns:     AX = near-random number between 0 and 65535
  570.              you may notice repeating patterns every few thousand calls
  571.              to Random.
  572. Uses:        AX
  573. Example:     call   random
  574.  
  575.  
  576.  
  577. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  578.  
  579. RSET:        right-justifies a string in a fixed field
  580. Source:      rset.asm (strlen.asm)
  581.  
  582. Call with:   EDI = address of field string
  583.              ESI = address of string to be justified in the field
  584.              Both strings must be zero-terminated (ASCIIZ).  The field
  585.              string may not contain any nul characters except for the
  586.              terminator.
  587. Returns:     CF = 0 if no error
  588.              CF = 1 if string was truncated to fit in the field
  589. Uses:        CF; all other flags and registers saved
  590. Example:
  591.              lea   edi,field             ; field string
  592.              lea   esi,source            ; string to be justified in field
  593.              call  rset
  594.  
  595.  
  596. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  597.  
  598. RTRIM:       removes trailing blanks from an ASCIIZ string
  599. Source:      rtrim.asm (strlen.asm)
  600.  
  601. Call with:   EBX pointing to string
  602. Returns:     ECX = new string length
  603. Uses:        ECX
  604. Example:     lea    ebx,string
  605.              call   rtrim
  606.  
  607.  
  608.  
  609. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  610.  
  611. SORTI2HI:    sort an array of 2-byte signed integers, highest first
  612. Source:      sorti2hi.asm
  613.  
  614. SORTI4HI:    sort an array of 4-byte signed integers, highest first
  615. Source:      sorti4hi.asm
  616.  
  617. SORTI2LO:    sort an array of 2-byte signed integers, lowest first
  618. Source:      sorti2lo.asm
  619.  
  620. SORTI4LO:    sort an array of 4-byte signed integers, lowest first
  621. Source:      sorti4lo.asm
  622.  
  623. Call with:   ES:[EDI] = address of first element of array to sort
  624.              ECX = number of array elements
  625.               SortI4 assumes ECX < 1 Gigabyte
  626.               SortI2 assumes ECX < 2 Gigabytes
  627.  
  628. Returns:     nothing
  629. Uses:        nothing; all registers and flags are saved
  630. Example:
  631.  
  632. extrn   sorti4hi:near
  633.  
  634. include dataseg.inc
  635. i4data  dd 1500 dup(0)
  636. @curseg ends
  637.  
  638. include codeseg.inc
  639.  
  640.              .      ; program establishes data values
  641.              .
  642.              .
  643.         lea    edi,i4data
  644.         push   ds
  645.         pop    es
  646.         mov    ecx,1500
  647.         call   sorti4hi
  648.  
  649.  
  650.  
  651. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  652.  
  653. SORTU2HI:    sort an array of 2-byte unsigned integers, highest first
  654. Source:      sortu2hi.asm
  655.  
  656. SORTU4HI:    sort an array of 4-byte unsigned integers, highest first
  657. Source:      sortu4hi.asm
  658.  
  659. SORTU2LO:    sort an array of 2-byte unsigned integers, lowest first
  660. Source:      sortu2lo.asm
  661.  
  662. SORTU4LO:    sort an array of 4-byte unsigned integers, lowest first
  663. Source:      sortu4lo.asm
  664.  
  665. Call with:   ES:[EDI] = address of first element of array to sort
  666.              ECX = number of array elements
  667.               SortI4 assumes ECX < 1 Gigabyte
  668.               SortI2 assumes ECX < 2 Gigabytes
  669.  
  670. Returns:     nothing
  671. Uses:        nothing; all registers and flags are saved
  672. Example:
  673.  
  674. extrn   sortu4hi:near
  675.  
  676. include dataseg.inc
  677. u4data  dd 1500 dup(0)
  678. @curseg ends
  679.  
  680. include codeseg.inc
  681.  
  682.              .      ; program establishes data values
  683.              .
  684.              .
  685.         lea    edi,u4data
  686.         push   ds
  687.         pop    es
  688.         mov    ecx,1500
  689.         call   sortu4hi
  690.  
  691.  
  692.  
  693. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  694.  
  695. STRTOI4:     converts an ASCII string to an integer value
  696. STRNTOI4:    converts n bytes of an ASCII string to an integer value
  697. Source:      strtoi4.asm
  698.  
  699. Call with:   ESI = address of string
  700.              strntoi4 only: ECX = number of bytes to read
  701. Returns:     EAX = integer value
  702.              strtoi4:  ESI points to character past terminating byte
  703.              strntoi4: if ECX = 0, ESI points to next character
  704.                        if ECX <> 0, ESI points to character past
  705.                        terminating byte
  706.              BL = error code
  707.                 bit 0 if set = CR read before reading any numeric characters
  708.                 bit 1 if set = CR was the terminating character
  709.                 bit 6 if set = overflow; result in EAX is unusable
  710.                 bit 7 if set = result is unsigned; result is unusable if the
  711.                                value represented by the string was negative
  712. Uses:        EAX, EBX, ECX, ESI, flags
  713. Example:
  714.  
  715. include codeseg.inc
  716.  
  717. ; data
  718.  
  719. number_string  db '1234567',0
  720.  
  721. ; code
  722.         .
  723.         .
  724.         .
  725.  
  726.         lea    esi,number_string   ; point to '1234567'
  727.         mov    ecx,7               ; 7-byte field
  728.         call   strntoi4            ; return result as an integer in EAX
  729.  
  730.  
  731.  
  732.  
  733. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  734.  
  735. STRCAT:      catenates (combines) two ASCIIZ strings
  736. Source:      strcat.asm (strdup.asm, strlen.asm)
  737.  
  738. Call with:   ESI = address of first string
  739.              EBX = address of second string
  740. Returns:     if CF = 0, EBX = address of combined ASCIIZ string
  741.              if CF = 1, insufficient memory available (not likely)
  742. Uses:        EBX, ECX, CF
  743. Example:
  744.  
  745. include codeseg.inc
  746.  
  747. extrn   strcat:near
  748.  
  749. ; data
  750. string0 db 'this string goes first',0
  751. string1 db ' this one is added at the end of the first',0
  752.  
  753. ; code
  754.        .
  755.        .
  756.        .
  757.        lea    esi,string0       ; address of first string
  758.        lea    ebx,string1       ; address of second string
  759.        call   strcat            ; result returned at EBX
  760.        jc     no_memory         ; original strings are undisturbed
  761.  
  762.  
  763.  
  764. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  765.  
  766. STRCHR:      search an ASCIIZ string for a specified character
  767. STRNCHR:     search n bytes of an ASCII string for a specified character
  768. Source:      strchr.asm (strlen.asm)
  769.  
  770. Call with:   EBX = pointer to ASCIIZ string
  771.              AL = character to find
  772.              ECX = number of bytes to search (strnchr only)
  773. Returns:     ECX = string length
  774.              if CF = 0, EAX is the offset from EBX to matching character
  775.              in the source string
  776.              if CF = 1, no matching character found
  777. Uses:        ECX, EAX, CF
  778.  
  779. Example on next page
  780.  
  781. ; use STRNCHR to determine if a key pressed was a legal key
  782. include codeseg.inc
  783.  
  784. extrn   strnchr:proc, getkey:proc, toupper:proc
  785.  
  786. ; data
  787.  
  788. valid_string db 'ABC123',27      ; keys 1,2,3,A,B,C and Esc
  789. valid_len    equ $-valid_string  ; number of valid keys
  790.  
  791. dispatch_table label word
  792.         dd akey, bkey, ckey, onekey, twokey, threekey, esckey
  793.  
  794. ; code
  795.         .
  796.         .
  797.         .
  798. get_another:
  799.         lea   ebx,valid_string ; EBX points to a string of valid keys
  800.         call  getkey           ; keycode returned in EAX
  801.         shr   ah,1             ; test for extended keycode
  802.         jc    get_another      ; I'm not interested in extended keycodes today
  803.  
  804.         call  toupper          ; convert keycode to upper case
  805.         mov   ecx,valid_len
  806.         call  strnchr
  807.         jc    get_another      ; CF = 1 if key pressed is not among the
  808.                                ; keys in the validation string
  809.         mov   ebx,eax
  810.         shl   ebx,1            ; convert byte offset to word offset
  811.         jmp   dispatch_table[ebx]
  812.  
  813. akey:   .
  814.         .
  815.         .
  816.  
  817. bkey:   .
  818.         .
  819.         .
  820.  
  821. ckey:   .
  822.         .
  823.         .
  824.  
  825. ; etc
  826.  
  827.  
  828.  
  829. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  830.  
  831. STRCMP:      compare strings, case-sensetive
  832. Source:      strcmp.asm (strlen.asm)
  833.  
  834. Call with:   DS:[ESI] pointing to string1
  835.              ES:[EDI] pointing to string2
  836. Returns:     if string1 < string2, SF = 1
  837.              if string1 = string2, ZF = 1
  838.              if string1 > string2, SF = 0, ZF = 0
  839.              Note that 'A' < 'a',  and that 'a' < 'z'.  Both strings must
  840.              be NUL-terminated ASCII strings.
  841. Uses:        flags; all registers are saved
  842. See also:    STRICMP, case-insensetive string comparison
  843.  
  844. Example:
  845.  
  846. include model.inc
  847.  
  848. extrn   strcmp:near
  849.  
  850. include dataseg.inc
  851.  
  852. string1 db 'Maple',0
  853. string2 db 'Oak',0
  854.  
  855. @curseg ends
  856.  
  857. include codeseg.inc
  858.  
  859.        .
  860.        .
  861.        .
  862. ; make sure ES = DS
  863.        mov      ax,ds
  864.        mov      es,ax
  865.        lea      esi,string1        ; DS:[SI] points to string1
  866.        lea      edi,string2        ; ES:[DI] points to string2
  867.        call     strcmp
  868.        je       short they_are_the_same
  869.        jns      short string2_GT_string1
  870.  
  871. ; string1 < string2
  872.        .
  873.        .
  874.  
  875.  
  876. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  877.  
  878. STRCPY:      copy an ASCIIZ string to existing buffer
  879. Source:      strcpy.asm (strlen.asm, strncpy.asm)
  880.  
  881. Call with:   ES:[EBX] pointing to ASCIIZ string
  882.              DS:[ESI] pointing to destination buffer
  883.              STRCPY assumes that the buffer is long enough to hold the
  884.              entire string.  The string's terminating NUL byte is not
  885.              copied to the buffer.
  886. Returns:     ECX = string length
  887. Uses:        ECX
  888.  
  889.  
  890. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  891.  
  892. STRNCPY:     copy ECX bytes to an existing buffer
  893. Source:      strncpy.asm
  894.  
  895. Call with:   ES:[EBX] pointing to ASCII string
  896.              DS:[ESI] pointing to destination buffer
  897.              ECX = number of bytes to copy
  898.              STRNCPY assumes that the buffer is long enough to hold the
  899.              entire string
  900. Returns:     nothing
  901. Uses:        nothing; all registers and flags are saved
  902. Example:
  903.  
  904. ; I want to copy a command line parameter to DGROUP
  905.  
  906. include asm.inc
  907. extrn   getcmd:near
  908. extrn   strncpy:near
  909.  
  910. include dataseg.inc
  911.  
  912. extrn   pspseg:word             ; PSP segment address was saved by STARTUP
  913. string_buffer   db 128 dup (?)
  914.  
  915. @curseg ends
  916.  
  917. include codeseg.inc
  918.        .
  919.        .
  920.        .
  921.        xor      eax,eax         ; first command line parameter
  922.        call     getcmd          ; returns parameter at ES:[EBX], length as ECX
  923.        jcxz     no_parameters
  924.        lea      esi,string_buffer
  925.        call     strncpy
  926.  
  927. ; make it zero-terminated
  928.        add      esi,ecx
  929.        mov      byte ptr [esi],0
  930.  
  931.  
  932. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  933.  
  934. STRICMP:     compare strings, case-insensetive
  935. Source:      strcmp.asm (strlen.asm)
  936.  
  937. Call with:   DS:[ESI] pointing to string1
  938.              ES:[EDI] pointing to string2
  939. Returns:     if string1 < string2, SF = 1
  940.              if string1 = string2, ZF = 1
  941.              if string1 > string2, SF = 0, ZF = 0
  942.              Note that 'A' = 'a',  and that 'a' < 'z'.  Both strings must
  943.              be NUL-terminated ASCII strings.
  944. Uses:        flags; all registers are saved
  945. See also:    STRCMP, case-sensetive string comparison
  946.  
  947. Example:
  948.  
  949. include model.inc
  950.  
  951. extrn   stricmp:near
  952.  
  953. include dataseg.inc
  954.  
  955. string1 db 'Maple',0
  956. string2 db 'Oak',0
  957.  
  958. @curseg ends
  959.  
  960. include codeseg.inc
  961.  
  962.        .
  963.        .
  964.        .
  965. ; make sure ES = DS
  966.        mov      ax,ds
  967.        mov      es,ax
  968.        lea      esi,string1        ; DS:[SI] points to string1
  969.        lea      edi,string2        ; ES:[DI] points to string2
  970.        call     strcmp
  971.        je       short they_are_the_same
  972.        jns      short string2_GT_string1
  973.  
  974. ; string1 < string2
  975.        .
  976.        .
  977.  
  978.  
  979. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  980.  
  981. STRINS:      inserts string1 in string0 at specified offset.
  982.              Creates new string in near memory; first part of new string
  983.              is n bytes of string0; middle of new string is string1; end
  984.              of new string is remainder of string0.
  985. Source:      strins.asm (strlen.asm)
  986.  
  987. Call with:   ESI pointing to string0
  988.              EBX pointing to string1
  989.              EAX = offset in string0 to insert string1
  990. Returns:     if CF = 1, insufficient memory (not likely)
  991.              if CF = 0, EBX points to new string
  992. Uses:        EBX, CF
  993. Example:
  994.  
  995. include codeseg.inc
  996.  
  997. extrn  strins:near
  998.  
  999. ; data
  1000. string0 db '1234567890',0
  1001. string1 db 'abcdefghij',0
  1002.  
  1003. ; code
  1004.        .
  1005.        .
  1006.        .
  1007.        lea    esi,string0       ; address of first string
  1008.        lea    ebx,string1       ; address of second string
  1009.        mov    eax,3             ; string1 inserted after '123'
  1010.        call   strins            ; result returned at EBX
  1011.        jc     no_memory         ; original strings are undisturbed
  1012.  
  1013.  
  1014.  
  1015. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1016.  
  1017. STRDUP:      duplicates an ASCIIZ string
  1018. Source:      strdup.asm (strlen.asm)
  1019.  
  1020. STRNDUP:     duplicates n bytes of a string
  1021. Source:      strdup.asm
  1022.  
  1023. Call with:   ES:[EBX] = address of source string
  1024.              (strndup) ECX = number of bytes to duplicate
  1025.              assumes DS:dataseg
  1026.  
  1027.              strdup requires an ASCIIZ string; strndup duplicates ECX
  1028.              characters at ES:[EBX] whether zero-terminated or not.  The
  1029.              duplicate created by strdup or strndup will be an ASCIIZ
  1030.              string.
  1031.  
  1032.              Version 2.0: Note that ES is not nessesarily = DS.  STRNDUP
  1033.              may be used to copy a string returned by EXENAME, PATH,
  1034.              or GETCMD to near data.
  1035.  
  1036. Returns:     if CF = 0, EBX = address of string copy in near memory
  1037.                         ECX = string length
  1038.              if CF = 1, insufficient memory in near memory (not likely)
  1039. Uses:        EBX, ECX, flags
  1040. Example:
  1041.              call  exename           ; get name of this program
  1042.                                      ; returns ES:[EBX] pointing to
  1043.                                      ; program name in environment
  1044.              call strdup             ; copy program name to near data
  1045.              jc   oops               ; not enough memory if CF = 1
  1046.                                      ; otherwise, EBX = address
  1047.                                      ; of string copy
  1048.  
  1049.  
  1050. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1051.              
  1052. STRIPCHR:    remove all occurances of a character from an ASCIIZ string.
  1053. Source:      stripchr.asm (strlen.asm)
  1054.  
  1055. Call with:   EBX = string address
  1056.              AL = character to remove from the string
  1057. Returns:     ECX = new string length
  1058. Uses:        ECX
  1059. Example:     lea    ebx,string        ; EBX -> string
  1060.              mov    al,'$'            ; remove "$" character from string
  1061.              call   stripchr
  1062.  
  1063.  
  1064. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1065.  
  1066. STRLEN:      finds length of an ASCIIZ string
  1067. Source:      strlen.asm
  1068.  
  1069. Call with:   EBX = address of the string
  1070. Returns:     ECX = length of string excluding the terminating NUL
  1071. Uses:        ECX
  1072. Example:     lea   ebx,string
  1073.              call  strlen
  1074.  
  1075.  
  1076. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1077.  
  1078. STRLWR:      changes upper-case characters in a string to lower case
  1079. Source:      strlwr.asm
  1080.  
  1081. STRNLWR:     changes a string of known length to lower case
  1082. Source:      strnlwr.asm
  1083.  
  1084. Call with:   EBX = address of an ASCIIZ string
  1085.              ECX = number of bytes (strnlwr only)
  1086. Returns:     nothing
  1087. Uses:        nothing
  1088. Example:     lea    ebx,string
  1089.              call   strlwr
  1090.  
  1091.  
  1092.  
  1093. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1094.  
  1095. STRRCHR:     find the last byte in a string matching AL
  1096. STRNRCHR:    find the last byte in n bytes matching AL
  1097. Source:      strrchr.asm (strlen.asm)
  1098.  
  1099. Call with:   EBX pointing to the first character of the string
  1100.              AL = byte to find
  1101.              (strnrchr only) ECX = number of bytes to search
  1102. Returns:     if CF = 1, no match
  1103.              if CF = 0, EAX = offset of the last matching byte from EBX
  1104. Uses:        EAX, CF; all other flags and registers are saved
  1105. Example:
  1106.  
  1107. include model.inc
  1108.  
  1109. extrn   strrchr:near
  1110.  
  1111. dataseg.inc
  1112. string  db 'my old computer was a real slug',0
  1113. @curseg ends
  1114.  
  1115. include codeseg.inc
  1116.         .
  1117.         .
  1118.         .
  1119.  
  1120.         mov   al,'w'         ; look for the lower-case "w"
  1121.         lea   ebx,string
  1122.         call  strrchr
  1123.         jc    oops           ; cut outta here if not in the string
  1124.                              ; else go on
  1125.  
  1126.  
  1127.  
  1128. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1129.  
  1130. STRREV:      reverses all characters in a string
  1131. STRNREV:     reverses n characters in a string
  1132. Source:      strrev.asm (strlen.asm)
  1133.  
  1134. Call with:   EBX pointing to the first character of the string
  1135.              ECX = number of bytes in string to reverse (strnrev only)
  1136. Returns:     ECX = string length
  1137. Uses:        ECX; all other registers and flags saved
  1138. Example:     lea   ebx,string         ; EBX points to ASCIIZ string
  1139.              call  strrev             ; also returns ECX = string length
  1140.  
  1141.  
  1142.  
  1143. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1144.  
  1145. STRSPACE:    creates an ASCIIZ string filled with the space character,
  1146.              terminated with NUL
  1147. Source:      strspace.asm
  1148.  
  1149. Call with:   EAX = string length (not including terminating NUL)
  1150. Returns:     if CF = 1, insufficient memory (not likely)
  1151.              if CF = 0, EBX points to the new string
  1152.                         ECX = string length (should be same as EAX)
  1153. Uses:        ECX, EBX, CF
  1154. Example:     mov   eax,14              ; make a new string 14 characters long
  1155.              call  strspace
  1156.              jc    short oops          ; not enough memory if CF = 1
  1157.              mov   string14,ebx        ; else save pointer to string
  1158.  
  1159.  
  1160. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1161.  
  1162. STRSET:      sets all bytes of an ASCIIZ string to a specified character
  1163. STRNSET:     sets n bytes of an ASCIIZ string to a specified character
  1164. Source:      strset.asm (strlen.asm)
  1165.  
  1166. Call with:   EBX pointing to a valid ASCIIZ string
  1167.              AL = character
  1168.              ECX = number of bytes to set (strnset only)
  1169. Returns:     ECX = string length
  1170. Uses:        ECX
  1171. Example:     lea   ebx,string          ; EBX points to an ASCIIZ string
  1172.              mov   al,'*'
  1173.              call  strset
  1174.  
  1175.  
  1176.  
  1177.  
  1178. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1179.  
  1180. STRSTR:      finds the first match with a target string in a source string
  1181.              case sensetive
  1182. Source:      strstr.asm ($strstr.asm, strlen.asm)
  1183.  
  1184. STRISTR:     finds the first match with a target string in a source string
  1185.              case insensetive
  1186. Source:      stristr.asm (strstr.asm, strdup.asm, strupr.asm)
  1187.  
  1188. STRRSTR:     finds the last match with a target string in a source string
  1189.              case sensetive
  1190. Source:      strrstr.asm (strrev.asm, $strstr.asm)
  1191.  
  1192. Call with:   DS:[EDI] pointing to source string
  1193.              DS:[ESI] pointing to target string.
  1194. Returns:     if CF = 0, EAX = offset of target in source string.
  1195.              if CF = 1, no match
  1196.  
  1197. Uses:        EAX, CF; all other flags and registers are saved
  1198. Example:
  1199.  
  1200. include model.inc
  1201.  
  1202. include dataseg.inc
  1203.  
  1204. string     db 'Monday',0
  1205. substring  db 'day',0
  1206.  
  1207. @curseg ends
  1208.  
  1209. include codeseg.inc
  1210.         .
  1211.         .
  1212.         .
  1213.         lea   edi,string       ; source = 'monday',0
  1214.         lea   esi,substring    ; target = 'day',0
  1215.                                ; find the offset of 'day' in 'Monday'
  1216.         call  strstr           ; in this example, strstr returns EAX = 3
  1217.  
  1218.  
  1219. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1220.  
  1221. STRUPR:      changes lower-case characters in an ASCIIZ string to upper case
  1222. Source:      strupr.asm
  1223.  
  1224. STRNUPR:     changes lower-case characters in an n-length string to upper case
  1225. Source:      strnupr.asm
  1226.  
  1227. Call with:   EBX pointing to string
  1228.              (strnupr only) ECX = number of bytes in string
  1229. Returns:     nothing
  1230. Uses:        nothing
  1231. Example:     mov    ebx,offset string
  1232.              mov    ecx,bytes
  1233.              call   strnupr
  1234.  
  1235.  
  1236.  
  1237. ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1238.  
  1239. SWAPB:       swaps ECX bytes at DS:[ESI] with the bytes at ES:[EDI]
  1240. Source:      swapb.asm
  1241.  
  1242. Call with:   ESI pointing to one of the data areas, EDI pointing
  1243.              to the other
  1244.              ECX = number of bytes to swap
  1245. Returns:     nothing
  1246. Uses:        nothing; all registers and flags are saved
  1247. Example:
  1248.  
  1249. include model.inc
  1250.  
  1251. extrn   swapb:near
  1252.  
  1253. include dataseg.inc
  1254.  
  1255. string1 db 'this is string 1',0
  1256. string2 db 'this is string 2',0
  1257.  
  1258. strings dw string1, string2         ; addresses of the strings
  1259.                                     ; this trivial example will swap
  1260.                                     ; the string pointers
  1261. @curseg ends
  1262.  
  1263. include codeseg.inc
  1264.  
  1265. public  stringswap
  1266. stringswap   proc near
  1267.          .
  1268.          .
  1269.          .
  1270.          lea   esi,strings
  1271.          mov   edi,esi
  1272.          mov   eax,2                 ; each string pointer is 2 bytes
  1273.          add   edi,eax               ; point to 2nd pointer
  1274.          call  swapb
  1275.